﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SpeedTestReports.XAMLReports;
using System.Windows.Markup;
using System.IO;
using System.IO.IsolatedStorage;
using System.Security.Cryptography;
using System.Security.Permissions;

namespace SpeedTestReports
{
    public partial class MainPage : UserControl
    {
        private string userName = String.Empty;
        private string password = String.Empty;
        private GenericKeyValue hackValue = new GenericKeyValue(); //trying to get the app to recognize this.
        private DashboardForm dash = null;

        public MainPage()
        {
            InitializeComponent();
        }

        private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
        {
            string userName = String.Empty;
            string password = String.Empty;
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForSite();
            if (storage != null)
            {
                if (storage.DirectoryExists("SpeedTest") && storage.FileExists(System.IO.Path.Combine("SpeedTest", "UserData.txt")))
                {
                    IsolatedStorageFileStream fs = new IsolatedStorageFileStream(System.IO.Path.Combine("SpeedTest", "UserData.txt"), FileMode.Open, storage);
                    StreamReader reader = new StreamReader(fs);

                    userName = reader.ReadLine();
                    password = reader.ReadLine();

                    reader.Close();
                }
            }

            LoginForm login = new LoginForm();
            login.Password = password;
            login.UserName = userName;
            login.Closed += new EventHandler(login_Closed);
            login.Show();

        }

        void login_Closed(object sender, EventArgs e)
        {
            LoginForm login = (LoginForm)sender;
            userName = login.UserName;
            password = login.Password;

            if ((bool)login.DialogResult)
            {
                try
                {
                    this.Cursor = Cursors.Wait;
                    XAMLReportsSoapClient client = new XAMLReportsSoapClient();
                    client.AuthenticateUserCompleted += new EventHandler<AuthenticateUserCompletedEventArgs>(client_AuthenticateUserCompleted);
                    client.AuthenticateUserAsync(userName, password);
                    
                }
                catch (Exception ex)
                {

                }
            }
        }

        void client_AuthenticateUserCompleted(object sender, AuthenticateUserCompletedEventArgs e)
        {
            if (e.Result)
            {
                XAMLReportsSoapClient client = new XAMLReportsSoapClient();
                client.GetReportListCompleted += new EventHandler<GetReportListCompletedEventArgs>(client_GetReportListCompleted);
                client.GetReportListAsync(userName, password);
            }
            else
            {
                this.Cursor = Cursors.Arrow;
                LoginForm login = new LoginForm();
                login.Closed += new EventHandler(login_Closed);
                login.lblStatus.Text = "Login Failed. Please try again";
                login.Show();
            }
        }

        void client_GetReportListCompleted(object sender, GetReportListCompletedEventArgs e)
        {

            this.Cursor = Cursors.Arrow;

            string reportListXaml = e.Result.ToString();
            this.ReportList.Children.Clear();
            this.ReportList.Children.Add((TreeView)XamlReader.Load(reportListXaml));
            TreeView reportTree = null;

            for (int i = 0; i < this.ReportList.Children.Count; i++)
            {
                if (ReportList.Children[i].GetType() == typeof(TreeView))
                {
                    reportTree = (TreeView)ReportList.Children[i];
                }
            }

            if (reportTree != null)
            {
                reportTree.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(treeReports_SelectedItemChanged);
            }
        }

        private void btnDashboard_Click(object sender, RoutedEventArgs e)
        {
            DashboardForm dashboard = new DashboardForm();
            dashboard.Closed += new EventHandler(dashboard_Closed);
            dashboard.Width = this.ActualWidth;
            dashboard.Height = this.ActualHeight;
            dashboard.dashboardViewer.Height = this.ActualHeight;
            dashboard.dashboardViewer.Width = this.ActualWidth;
            dashboard.Password = password;
            dashboard.UserName = userName;
            dash = dashboard;

            Application.Current.Host.Content.IsFullScreen = true;

            dashboard.Show();
        }

        void dashboard_Closed(object sender, EventArgs e)
        {
            dash = null;
        }


        void client_GetNextSelectorCompleted(object sender, GetNextSelectorCompletedEventArgs e)
        {
            this.Cursor = Cursors.Arrow;

            string critXaml = e.Result.ToString();
            this.pnlContent.Children.Clear();
            this.pnlContent.Children.Add((UIElement)XamlReader.Load(critXaml));    //example only

            SetButtonEvents();
        }

        void client_GetSelectorCompleted(object sender, GetSelectorCompletedEventArgs e)
        {
            this.Cursor = Cursors.Arrow;

            string critXaml = e.Result.ToString();
            this.pnlContent.Children.Clear();
            this.pnlContent.Children.Add((UIElement)XamlReader.Load(critXaml));    //example only

            SetButtonEvents();
        }

        private void SetButtonEvents()
        {
            Button submitButton = null;
            Border selBorder = (Border)FindChildByType(typeof(Border), pnlContent.Children);
            StackPanel stack = (StackPanel)selBorder.Child;
            if (stack != null)
            {
                submitButton = (Button)FindChildByType(typeof(Button), stack.Children);
                if (submitButton != null)
                {
                    if (submitButton.Content.ToString().ToUpper().Equals("SUBMIT"))
                    {
                        submitButton.Click += new RoutedEventHandler(submitButton_Click);
                    }
                    else  //it's the NEXT button, which means there are more selectors to get.
                    {
                        submitButton.Click += new RoutedEventHandler(nextButton_Click);
                    }
                }
            }
        }

        private UIElement FindChildByType(Type childType, UIElementCollection children)
        {
            if (childType == null || children == null) { return null; }

            for (int i = 0; i < children.Count; i++)
            {
                if (children[i].GetType() == childType)
                {
                    return children[i];
                }
            }

            return null;
        }

        void nextButton_Click(object sender, RoutedEventArgs e)
        {
            Button submitButtton = (Button)sender;

            Border selBorder = (Border)FindChildByType(typeof(Border), pnlContent.Children);
            StackPanel selStackPanel = (StackPanel)selBorder.Child;
            if (selStackPanel != null)
            {
                UIElementCollection selectionControls = selStackPanel.Children;

                Type[] childTypes = new Type[3] { typeof(STComboBox), typeof(STTextBox), typeof(STDatePicker) };
                List<UIElement> typeMatches = new List<UIElement>();

                for (int i = 0; i < selectionControls.Count; i++)
                {
                    if (selectionControls[i].GetType() == typeof(StackPanel))
                    {
                        StackPanel sp = (StackPanel)selectionControls[i];
                        FindChildrenByType(ref typeMatches, childTypes, sp.Children);
                    }
                }

                List<SelectionValue> selValues = new List<SelectionValue>();
                if (ValidateSelectionInputs(typeMatches, ref selValues))
                {
                    //clear selectors
                    this.pnlContent.Children.Clear();
                    this.Cursor = Cursors.Wait;

                    XAMLReportsSoapClient client = new XAMLReportsSoapClient();
                    client.GetNextSelectorCompleted += new EventHandler<GetNextSelectorCompletedEventArgs>(client_GetNextSelectorCompleted);

                    string btnTag = (string)submitButtton.Tag;
                    string[] btnTags = btnTag.Split(':');
                    string reportID = String.Empty;
                    string sequence = String.Empty;
                    if (btnTags.Length > 1) 
                    { 
                        reportID = btnTags[0];
                        sequence = btnTags[1];
                        int nextSeq = Int32.Parse(sequence);
                        nextSeq++;
                        sequence = nextSeq.ToString();
                    }

                    client.GetNextSelectorAsync(userName, password,sequence, reportID, selValues);
                }
                else
                {
                    //TODO: error here
                }
            }
        }

        void submitButton_Click(object sender, RoutedEventArgs e)
        {
            //Validate the control values and submit the report if all is okay, otherwise display error
            //Children are encased in stackpanels, which are children of pnlContent
                        
            Button submitButtton = (Button)sender;

            Border selBorder = (Border)FindChildByType(typeof(Border), pnlContent.Children);
            StackPanel selStackPanel = (StackPanel)selBorder.Child;
            if (selStackPanel != null)
            {
                UIElementCollection selectionControls = selStackPanel.Children;

                Type[] childTypes = new Type[3] { typeof(STComboBox), typeof(STTextBox), typeof(STDatePicker) };
                List<UIElement> typeMatches = new List<UIElement>();

                for (int i = 0; i < selectionControls.Count; i++)
                {
                    if (selectionControls[i].GetType() == typeof(StackPanel))
                    {
                        StackPanel sp = (StackPanel)selectionControls[i];
                        FindChildrenByType(ref typeMatches, childTypes, sp.Children);
                    }
                }

                List<SelectionValue> selValues = new List<SelectionValue>();
                if(ValidateSelectionInputs(typeMatches, ref selValues))
                {
                    //clear selectors
                    this.pnlContent.Children.Clear();
                    this.Cursor = Cursors.Wait;

                    XAMLReportsSoapClient client = new XAMLReportsSoapClient();
                    client.GetReportCompleted +=new EventHandler<GetReportCompletedEventArgs>(client_GetReportCompleted);

                    string btnTag = (string)submitButtton.Tag;
                    string[] btnTags = btnTag.Split(':');
                    string reportID = String.Empty;
                    if (btnTags.Length > 0) { reportID = btnTags[0]; }

                    client.GetReportAsync(userName, password, reportID, selValues);
                }
                else
                {
                    //TODO: error here
                }
            }
        }

        private bool ValidateSelectionInputs(List<UIElement> inputs, ref List<SelectionValue> selValues)
        {
            //SpeedTestReports.Web.Selection sel = new SpeedTestReports.Web.Selection();
            //SpeedTestReports.Web.SelectionUtil.Deserialize(inputs[0]);
 
            for (int i = 0; i < inputs.Count; i++)
            {
                if (inputs[i].GetType() == typeof(STTextBox))
                {
                    STTextBox text = (STTextBox)inputs[i];
                    SelectionValue sv = new SelectionValue();
                    sv.Name = text.ParameterName;

                    if (text.IsEnabled)
                    {
                        if (text.Text != null)
                        {
                            sv.Value = text.Text;
                            sv.Text = text.Text;
                            selValues.Add(sv);
                        }
                        else
                        {
                            if (text.IsRequired)
                            {
                                return false;
                            }
                        }
                    }
                }
                
                if (inputs[i].GetType() == typeof(STComboBox))
                {
                    STComboBox combo = (STComboBox)inputs[i];
                    SelectionValue sv = new SelectionValue();
                    sv.Name = combo.ParameterName;

                    ComboBoxItem selItem = (ComboBoxItem)combo.SelectedItem;
                    if (combo.IsEnabled)
                    {
                        if (selItem != null)
                        {
                            sv.Value = (string)selItem.Tag;
                            sv.Text = selItem.Content.ToString();
                            selValues.Add(sv);
                        }
                        else
                        {
                            if (combo.IsRequired)
                            {
                                return false;
                            }
                        }
                    }
                }

                if (inputs[i].GetType() == typeof(STDatePicker))
                {
                    STDatePicker picker = (STDatePicker)inputs[i];
                    SelectionValue sv = new SelectionValue();
                    sv.Name = picker.ParameterName;

                    if (picker.IsEnabled)
                    {
                        if (picker.Text != null)
                        {
                            sv.Value = "'" + picker.Text + "'";
                            sv.Text = "'" + picker.Text + "'";
                            selValues.Add(sv);
                        }
                        else
                        {
                            if (picker.IsRequired)
                            {
                                return false;
                            }
                        }
                    }
                }

            }
            return true;
        }

        private void FindChildrenByType(ref List<UIElement> typeMatches, Type[] childTypes, UIElementCollection children)
        {
            if (childTypes == null || children == null) { return; }

            for (int i = 0; i < children.Count; i++)
            {
                for (int j = 0; j < childTypes.Length; j++)
                {
                    if (children[i].GetType() == childTypes[j])
                    {
                        typeMatches.Add(children[i]);
                    }
                }
            }
        }

        void client_GetReportCompleted(object sender, GetReportCompletedEventArgs e)
        {
            this.Cursor = Cursors.Arrow;

            string reportXaml = e.Result.ToString();
            this.reportViewer.Content = "";
            this.reportViewer.Content = ((UIElement)XamlReader.Load(reportXaml));    //example only
            reportViewer.Visibility = Visibility.Visible;
            SizeReportViewer();

        }

        private void treeReports_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            //hide any previous report.
            reportViewer.Content = "";
            reportViewer.Visibility = Visibility.Collapsed;

            TreeViewItem tvi = (TreeViewItem)e.NewValue;
            
            if(!String.IsNullOrEmpty(tvi.Name) && tvi.Name.Contains("Report"))
            {
                this.Cursor = Cursors.Wait;

                string reportID = (string)tvi.Tag;

                XAMLReportsSoapClient client = new XAMLReportsSoapClient();
                client.GetSelectorCompleted +=new EventHandler<GetSelectorCompletedEventArgs>(client_GetSelectorCompleted);
                client.GetSelectorAsync(userName, password, reportID);
            }
        }

        private void MainForm_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            //resize report viewer if it is visible
            SizeReportViewer();
        }

        private void SizeReportViewer()
        {
            if (reportViewer.Visibility == Visibility.Visible)
            {
                reportViewer.Width = contentColumn.ActualWidth - (pnlContent.Margin.Left + pnlContent.Margin.Right);
                reportViewer.Height = contentRow.ActualHeight - (pnlContent.Margin.Top + pnlContent.Margin.Bottom);
            }

            if (dash != null)
            {
                dash.Height = this.ActualHeight;
                dash.Width = this.ActualWidth;
                dash.dashboardViewer.Width = this.ActualWidth;
                dash.dashboardViewer.Height = this.ActualHeight;
            }
        }

        private void btnLogOut_Click(object sender, RoutedEventArgs e)
        {
            userName = String.Empty;
            password = String.Empty;

            LoginForm login = new LoginForm();
            login.Closed += new EventHandler(login_Closed);
            login.Show();
        }

        private void btnAdminPanel_Click(object sender, RoutedEventArgs e)
        {

        }

        private void test_Click(object sender, RoutedEventArgs e)
        {

        }
    }
}
